const { src, dest, parallel, series, watch } = require('gulp')

const del = require('del')
const path = require('path')
const minimist = require('minimist')
const browserSync = require('browser-sync')

const loadPlugins = require('gulp-load-plugins')
const plugins = loadPlugins()
const bs = browserSync.create()
const cwd = process.cwd()
let config = {
  // default config
  build: {
    src: 'src',
    dist: 'dist',
    temp: 'temp',
    public: 'public',
    paths: {
      styles: 'assets/styles/*.scss',
      scripts: 'assets/scripts/*.js',
      images: 'assets/images/**',
      fonts: 'assets/fonts/**',
      pages: '**/*.html'
    },
    port: 2080,
    gitBranch: 'master',
    origin: ''
  }
}
try {
  const loadConfig = require(path.join(cwd, 'pages.config.js'))
  const packageUrl = require(`${cwd}/package.json`)
  console.log('packageUrl:', packageUrl)
  config = Object.assign({}, config, loadConfig)
} catch (e) {
  throw e
}
const clean = () => {
  return del([config.build.dist, config.build.temp])
}
const style = () => {
  return src(config.build.paths.styles, { base: config.build.src, cwd: config.build.src })
    .pipe(plugins.sass({ outputStyle: 'expanded' }))
    .pipe(dest(config.build.temp))
    .pipe(bs.reload({ stream: true }))
}
const script = () => {
  return src(config.build.paths.scripts, { base: config.build.src, cwd: config.build.src })
    .pipe(plugins.babel({ presets: [require('@babel/preset-env')] }))
    .pipe(dest(config.build.temp))
    .pipe(bs.reload({ stream: true }))
}
const page = () => {
  return src(config.build.paths.pages, { base: config.build.src, cwd: config.build.src })
    .pipe(plugins.swig({ data: config.data }))
    .pipe(dest(config.build.temp))
    .pipe(bs.reload({ stream: true }))
}
const image = () => {
  return src(config.build.paths.images, { base: config.build.src, cwd: config.build.src })
    .pipe(plugins.imagemin())
    .pipe(dest(config.build.dist))
}
const font = () => {
  return src(config.build.paths.fonts, { base: config.build.src, cwd: config.build.src })
    .pipe(plugins.imagemin())
    .pipe(dest(config.build.dist))
}
const extra = () => {
  return src('**', { base: config.build.public, cwd: config.build.public })
    .pipe(dest(config.build.dist))
}
const scriptLint = done => {
  // 代码检查
  return src([config.build.paths.scripts, '!node_modules/**'], { base: config.build.src, cwd: config.build.src })
    .pipe(plugins.eslint({
      rules: {
        'no-alert': 2,
        'no-empty': 2,
        camelcase: 1,
        quotes: 1,
        'no-console': 1
      },
      env: {
        es5: true,
        es6: true,
        node: true,
        jquery: true,
        browser: true
      }
    }))
    .pipe(plugins.eslint({ fix: true }))
    .pipe(plugins.eslint.format())
    .pipe(plugins.eslint.failAfterError())
  done()
}
const styleLint = (done) => {
  return src([config.build.paths.styles, '!node_modules/**'], { base: config.build.src, cwd: config.build.src })
    .pipe(plugins.sassLint())
    .pipe(plugins.sassLint.format())
    .pipe(plugins.sassLint.failOnError())
  done()
}
const cleanTmp = () => {
  return del(config.build.temp)
}
const serve = () => {
  watch(config.build.paths.styles, { cwd: config.build.src }, style)
  watch(config.build.paths.scripts, { cwd: config.build.src }, script)
  watch(config.build.paths.pages, { cwd: config.build.src }, page)
  watch(
    [
      config.build.paths.images,
      config.build.paths.fonts
    ],
    { cwd: config.build.src }, bs.reload)
  watch('**', { cwd: config.build.public }, bs.reload)
  bs.init({
    notify: false,
    port: 2080,
    server: {
      baseDir: [config.build.dist, config.build.src, config.build.public],
      routes: {
        '/node_modules': 'node_modules'
      }
    }
  })
}
const useref = () => {
  return src(config.build.paths.pages, { base: config.build.temp, cwd: config.build.temp })
    .pipe(plugins.useref({ searchPath: [config.build.temp, '.', '../'] }))
    // html js css
    .pipe(plugins.if(/\.js$/, plugins.uglify()))
    .pipe(plugins.if(/\.css$/, plugins.cleanCss()))
    .pipe(plugins.if(/\.html$/, plugins.htmlmin({
      collapseWhitespace: true, // 删除多余空格
      minifyCSS: true, // 压缩行内css
      minifyJS: true// 压缩行内js
    })))
    .pipe(dest(config.build.dist))
}
const finalDeploy = () => {
  return src(['**/*', '!node_modules/**'], { cwd: config.build.dist })
    .pipe(plugins.ghPages({
      remoteUrl: config.build.origin,
      branch: config.build.gitBranch
    }))
}
const compile = series(scriptLint, styleLint, parallel(style, script, page))
const lint = parallel(scriptLint, styleLint)
const start = series(compile, serve)
const build = series(clean, series(parallel(series(compile, useref), image, font, extra)))
const deploy = series(build, finalDeploy)
module.exports = {
  start,
  clean,
  lint,
  build,
  deploy,
  serve
}
